package com.lx.data.server

import java.io.{BufferedInputStream, DataInputStream, IOException}
import java.net.{ServerSocket, Socket}
import java.text.SimpleDateFormat
import java.util.Date

import com.alibaba.fastjson.JSONObject
import com.lx.data.server.config.DBConfig
import com.lx.data.server.entity.DBObj
import com.lx.data.server.entity.DBObj.centerReceive
import com.lx.data.server.config.DBConfig.db._


object Application {

  private class ClientHandler(var socket: Socket) extends Runnable {
    override def run(): Unit = {
      try {
        println("begin read data")
        val bis = new BufferedInputStream(socket.getInputStream)
        val dis = new DataInputStream(bis)
        val bytes = new Array[Byte](1)
        var ret = new StringBuilder
        while ( {
          dis.read(bytes) != -1
        }) {
          ret.append(bytesToHexString(bytes)).append(" ")
          if (dis.available == 0) {
            if (ret.toString().startsWith("7e 7e")) {
              DBConfig.db.run(DBObj.centerReceive.insert(lift(DBObj.CenterReceive(new Date, ret.toString()))))

              try {
                contentParse(ret.toString())
              } catch {
                case e: Exception =>
                  println("报文解析失败")
                  e.printStackTrace()
              }
            }
            println(socket.getRemoteSocketAddress + ":" + ret)
            ret = new StringBuilder
          }
        }
      } catch {
        case e: Exception =>
          e.printStackTrace()
      } finally {
        println("client is over")
        if (socket != null) try socket.close()
        catch {
          case e: IOException =>
            e.printStackTrace()
        }
      }
    }
  }

  /**
   * 报文解析
   *
   * @param str 报文
   */
  def contentParse(str: String): Unit = {
    val sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    val sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm")
    val strArr: Array[String] = str.split(" ")
    val centerAddr: String = strArr(2)
    val stationAddr: String = strArr(3) + strArr(4) + strArr(5) + strArr(6) + strArr(7)
    val sendTime: Date = sdf1.parse(
      "20" + strArr(strArr.indexOf("02") + 3)
        + "-"
        + strArr(strArr.indexOf("02") + 4)
        + "-"
        + strArr(strArr.indexOf("02") + 5)
        + " "
        + strArr(strArr.indexOf("02") + 6)
        + ":"
        + strArr(strArr.indexOf("02") + 7)
        + ":"
        + strArr(strArr.indexOf("02") + 8)
    )
    val dataTime: Date = sdf2.parse(
      "20" + strArr(strArr.indexOf("f0") + 2)
        + "-"
        + strArr(strArr.indexOf("f0") + 3)
        + "-"
        + strArr(strArr.indexOf("f0") + 4)
        + " "
        + strArr(strArr.indexOf("f0") + 5)
        + ":"
        + strArr(strArr.indexOf("f0") + 6)
    )
    val funcDesc = strArr(10)
    val stationType = strArr(strArr.indexOf("f0") - 1)
    val content = str.substring(str.indexOf("02"))
    val drp = if (content.contains("20")) {
      val strArrTmp = content.split(" ")
      BigDecimal.apply(
        strArrTmp(strArrTmp.indexOf("20") + 2)
          + strArrTmp(strArrTmp.indexOf("20") + 3)
          + strArrTmp(strArrTmp.indexOf("20") + 4))
        ./(10).setScale(1, BigDecimal.RoundingMode.HALF_DOWN)
    } else {
      null
    }
    val z = null
    println(drp)
    val list = DBConfig.db.run(
      DBObj.hydrologyData.filter(
        (h: DBObj.HydrologyData) =>
          h.dataTime.equals(lift(dataTime))
            && h.stationAddr.equals(lift(stationAddr))
      )
    )
    println(list)
    if (list.isEmpty) {
      val hydrologyData =  DBObj.HydrologyData(
        sendTime,
        dataTime,
        stationAddr,
        centerAddr,
        funcDesc,
        stationType,
        drp,
        z
      )
      println(hydrologyData)
      DBConfig.db.run(
        DBObj.hydrologyData.insert(
          lift(
            hydrologyData
          )
        )
      )
    }
  }

  def main(args: Array[String]): Unit = {
    val server = new ServerSocket(502)
    try {
      while ( {
        true
      }) {
        println("listening...")
        val socket = server.accept
        println("client addr: " + socket.getRemoteSocketAddress)
        println("connected...")
        val handler = new ClientHandler(socket)
        val t = new Thread(handler)
        t.start()
      }
    } catch {
      case e: Exception =>
        e.printStackTrace()
    } finally if (server != null) try server.close()
    catch {
      case e: IOException =>
        e.printStackTrace()
    }
  }

  def bytesToHexString(bytes: Array[Byte]): String = {
    val sb = new StringBuilder
    for (aByte <- bytes) {
      val hex = Integer.toHexString(0xFF & aByte)
      if (hex.length == 1) sb.append('0')
      sb.append(hex)
    }
    sb.toString
  }
}
